package com.aipartner.common;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Unified API Response Result
 * 
 * @author AI Partner Team
 * @since 2024-01-20
 * @param <T> Data type
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "API Response Result")
public class Result<T> {
    
    @ApiModelProperty(value = "Response code", example = "200")
    private Integer code;
    
    @ApiModelProperty(value = "Response message", example = "Success")
    private String message;
    
    @ApiModelProperty(value = "Response data")
    private T data;
    
    @ApiModelProperty(value = "Is success", example = "true")
    private Boolean success;
    
    /**
     * Success with data
     */
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(ResultCode.SUCCESS.getCode());
        result.setMessage(ResultCode.SUCCESS.getMessage());
        result.setData(data);
        result.setSuccess(true);
        return result;
    }
    
    /**
     * Success without data
     */
    public static <T> Result<T> success() {
        return success(null);
    }
    
    /**
     * Success with custom message
     */
    public static <T> Result<T> success(T data, String message) {
        Result<T> result = new Result<>();
        result.setCode(ResultCode.SUCCESS.getCode());
        result.setMessage(message);
        result.setData(data);
        result.setSuccess(true);
        return result;
    }
    
    /**
     * Fail with error code and message
     */
    public static <T> Result<T> fail(ResultCode resultCode) {
        Result<T> result = new Result<>();
        result.setCode(resultCode.getCode());
        result.setMessage(resultCode.getMessage());
        result.setSuccess(false);
        return result;
    }
    
    /**
     * Fail with custom message
     */
    public static <T> Result<T> fail(String message) {
        Result<T> result = new Result<>();
        result.setCode(ResultCode.INTERNAL_SERVER_ERROR.getCode());
        result.setMessage(message);
        result.setSuccess(false);
        return result;
    }
    
    /**
     * Fail with code and message
     */
    public static <T> Result<T> fail(Integer code, String message) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMessage(message);
        result.setSuccess(false);
        return result;
    }
    
    /**
     * Build custom result
     */
    public static <T> Result<T> build(T data, Integer code, String message) {
        Result<T> result = new Result<>();
        result.setData(data);
        result.setCode(code);
        result.setMessage(message);
        result.setSuccess(ResultCode.SUCCESS.getCode().equals(code));
        return result;
    }
}